<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Cross Site Request Forgery (CSRF) :: Spring Security</title>
<link rel="canonical" href="../../../features/exploits/csrf.html">
<link rel="prev" href="index.html">
<link rel="next" href="headers.html">
<meta name="generator" content="Antora 3.0.0">
<link rel="stylesheet" href="../../../_/css/site.css">
<link href="../../../_/img/favicon.ico" rel='shortcut icon' type='image/vnd.microsoft.icon'>
<link rel="stylesheet" href="../../../_/css/vendor/docsearch.min.css">

<script>var uiRootPath = '../../../_'</script>
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://spring.io">
<img id="springlogo" class="block" src="../../../_/img/spring-logo.svg" alt="Spring">
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<div class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="csrf.html#">Why Spring</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/why-spring">Overview</a>
<a class="navbar-item" href="https://spring.io/microservices">Microservices</a>
<a class="navbar-item" href="https://spring.io/reactive">Reactive</a>
<a class="navbar-item" href="https://spring.io/event-driven">Event Driven</a>
<a class="navbar-item" href="https://spring.io/cloud">Cloud</a>
<a class="navbar-item" href="https://spring.io/web-applications">Web Applications</a>
<a class="navbar-item" href="https://spring.io/serverless">Serverless</a>
<a class="navbar-item" href="https://spring.io/batch">Batch</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="csrf.html#">Learn</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/learn">Overview</a>
<a class="navbar-item" href="https://spring.io/quickstart">Quickstart</a>
<a class="navbar-item" href="https://spring.io/guides">Guides</a>
<a class="navbar-item" href="https://spring.io/blog">Blog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="csrf.html#">Projects</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/projects">Overview</a>
<a class="navbar-item" href="https://spring.io/projects/spring-boot">Spring Boot</a>
<a class="navbar-item" href="https://spring.io/projects/spring-framework">Spring Framework</a>
<a class="navbar-item" href="https://spring.io/projects/spring-cloud">Spring Cloud</a>
<a class="navbar-item" href="https://spring.io/projects/spring-cloud-dataflow">Spring Cloud Data Flow</a>
<a class="navbar-item" href="https://spring.io/projects/spring-data">Spring Data</a>
<a class="navbar-item" href="https://spring.io/projects/spring-integration">Spring Integration</a>
<a class="navbar-item" href="https://spring.io/projects/spring-batch">Spring Batch</a>
<a class="navbar-item" href="https://spring.io/projects/spring-security">Spring Security</a>
<a class="navbar-item navbar-item-special" href="https://spring.io/projects">View all projects</a>
<a class="navbar-item" href="https://spring.io/tools">Spring Tools 4</a>
<a class="navbar-item navbar-item-special-2" href="https://start.spring.io">Spring Initializr <svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><polyline points="15 10.94 15 15 1 15 1 1 5.06 1" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></polyline><polyline points="8.93 1 15 1 15 7.07" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></polyline><line x1="15" y1="1" x2="8" y2="8" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></line></svg></a>
</div>
</div>
<a class="navbar-item" href="https://spring.io/training">Training</a>
<a class="navbar-item" href="https://spring.io/support">Support</a>
<div class="navbar-item has-dropdown is-hoverable is-community">
<a class="navbar-link" href="csrf.html#">Community</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/community">Overview</a>
<a class="navbar-item" href="https://spring.io/events">Events</a>
<a class="navbar-item" href="https://spring.io/team">Team</a>
</div>
</div>
</div>
</div>
<div id="switch-theme">
<input type="checkbox" id="switch-theme-checkbox" />
<label for="switch-theme-checkbox">Dark Theme</label>
</div>
</nav>
</header>
<div class="body">
<div class="nav-container" data-component="ROOT" data-version="5.6.1">
<aside class="nav">
<div class="panels">
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../index.html">Spring Security</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../index.html">Overview</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../prerequisites.html">Prerequisites</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../community.html">Community</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../whats-new.html">What&#8217;s New</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../getting-spring-security.html">Getting Spring Security</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../index.html">Features</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../authentication/index.html">Authentication</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/password-storage.html">Password Storage</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item is-current-page" data-depth="3">
<a class="nav-link" href="csrf.html">CSRF</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="headers.html">HTTP Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="http.html">HTTP Requests</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../integrations/index.html">Integrations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/cryptography.html">Cryptography</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/data.html">Spring Data</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/concurrency.html">Java&#8217;s Concurrency APIs</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/jackson.html">Jackson</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/localization.html">Localization</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../modules.html">Project Modules</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../samples.html">Samples</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/index.html">Servlet Applications</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../servlet/getting-started.html">Getting Started</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../servlet/architecture.html">Architecture</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/authentication/index.html">Authentication</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/architecture.html">Authentication Architecture</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/authentication/passwords/index.html">Username/Password</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/authentication/passwords/input.html">Reading Username/Password</a>
<ul class="nav-list">
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/form.html">Form</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/basic.html">Basic</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/digest.html">Digest</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="4">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/authentication/passwords/storage.html">Password Storage</a>
<ul class="nav-list">
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/in-memory.html">In Memory</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/jdbc.html">JDBC</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/user-details.html">UserDetails</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/user-details-service.html">UserDetailsService</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/password-encoder.html">PasswordEncoder</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/dao-authentication-provider.html">DaoAuthenticationProvider</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../../servlet/authentication/passwords/ldap.html">LDAP</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/session-management.html">Session Management</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/rememberme.html">Remember Me</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/openid.html">OpenID</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/anonymous.html">Anonymous</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/preauth.html">Pre-Authentication</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/jaas.html">JAAS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/cas.html">CAS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/x509.html">X509</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/runas.html">Run-As</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/logout.html">Logout</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authentication/events.html">Authentication Events</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/authorization/index.html">Authorization</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/architecture.html">Authorization Architecture</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/authorize-http-requests.html">Authorize HTTP Requests</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/authorize-requests.html">Authorize HTTP Requests with FilterSecurityInterceptor</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/expression-based.html">Expression-Based Access Control</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/secure-objects.html">Secure Object Implementations</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/method-security.html">Method Security</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/authorization/acls.html">Domain Object Security ACLs</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/oauth2/index.html">OAuth2</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/oauth2/login/index.html">OAuth2 Log In</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/login/core.html">Core Configuration</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/login/advanced.html">Advanced Configuration</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/oauth2/client/index.html">OAuth2 Client</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/client/core.html">Core Interfaces and Classes</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/client/authorization-grants.html">OAuth2 Authorization Grants</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/client/client-authentication.html">OAuth2 Client Authentication</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/client/authorized-clients.html">OAuth2 Authorized Clients</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/oauth2/resource-server/index.html">OAuth2 Resource Server</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/resource-server/jwt.html">JWT</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/resource-server/opaque-token.html">Opaque Token</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/resource-server/multitenancy.html">Multitenancy</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/oauth2/resource-server/bearer-tokens.html">Bearer Tokens</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/saml2/index.html">SAML2</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/saml2/login/index.html">SAML2 Log In</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/saml2/login/overview.html">SAML2 Log In Overview</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/saml2/login/authentication-requests.html">SAML2 Authentication Requests</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/saml2/login/authentication.html">SAML2 Authentication Responses</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/saml2/logout.html">SAML2 Logout</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/saml2/metadata.html">SAML2 Metadata</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/exploits/index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/exploits/csrf.html">Cross Site Request Forgery (CSRF) for Servlet Environments</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/exploits/headers.html">Security HTTP Response Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/exploits/http.html">HTTP</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/exploits/firewall.html">HttpFirewall</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/integrations/index.html">Integrations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/concurrency.html">Concurrency</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/jackson.html">Jackson</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/localization.html">Localization</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/servlet-api.html">Servlet APIs</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/data.html">Spring Data</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/mvc.html">Spring MVC</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/websocket.html">WebSocket</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/cors.html">Spring&#8217;s CORS Support</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/integrations/jsp-taglibs.html">JSP Taglib</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Configuration</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/configuration/java.html">Java Configuration</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/configuration/kotlin.html">Kotlin Configuration</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/configuration/xml-namespace.html">Namespace Configuration</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/test/index.html">Testing</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/method.html">Method Security</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/mockmvc/index.html">MockMvc Support</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/mockmvc/setup.html">MockMvc Setup</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/test/mockmvc/request-post-processors.html">Security RequestPostProcessors</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/authentication.html">Mocking Users</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/csrf.html">Mocking CSRF</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/form-login.html">Mocking Form Login</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/http-basic.html">Mocking HTTP Basic</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/oauth2.html">Mocking OAuth2</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/test/mockmvc/logout.html">Mocking Logout</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/mockmvc/request-builders.html">Security RequestBuilders</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/mockmvc/result-matchers.html">Security ResultMatchers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/test/mockmvc/result-handlers.html">Security ResultHandlers</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/appendix/index.html">Appendix</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/appendix/database-schema.html">Database Schemas</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../servlet/appendix/namespace/index.html">XML Namespace</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/appendix/namespace/authentication-manager.html">Authentication Services</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/appendix/namespace/http.html">Web Security</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/appendix/namespace/method-security.html">Method Security</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/appendix/namespace/ldap.html">LDAP Security</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../servlet/appendix/namespace/websocket.html">WebSocket Security</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../servlet/appendix/faq.html">FAQ</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/index.html">Reactive Applications</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../reactive/getting-started.html">Getting Started</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Authentication</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authentication/x509.html">X.509 Authentication</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authentication/logout.html">Logout</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Authorization</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authorization/method.html">EnableReactiveMethodSecurity</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/oauth2/index.html">OAuth2</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/oauth2/login/index.html">OAuth2 Log In</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/login/core.html">Core Configuration</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/login/advanced.html">Advanced Configuration</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/oauth2/client/index.html">OAuth2 Client</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/client/core.html">Core Interfaces and Classes</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/client/authorization-grants.html">OAuth2 Authorization Grants</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/client/client-authentication.html">OAuth2 Client Authentication</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/client/authorized-clients.html">OAuth2 Authorized Clients</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/oauth2/resource-server/index.html">OAuth2 Resource Server</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/resource-server/jwt.html">JWT</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/resource-server/opaque-token.html">Opaque Token</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/resource-server/multitenancy.html">Multitenancy</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/oauth2/resource-server/bearer-tokens.html">Bearer Tokens</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/exploits/index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/csrf.html">CSRF</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/headers.html">Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/http.html">HTTP Requests</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Integrations</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/integrations/cors.html">CORS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/integrations/rsocket.html">RSocket</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/test/index.html">Testing</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/test/method.html">Testing Method Security</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/test/web/index.html">Testing Web Security</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/test/web/setup.html">WebTestClient Setup</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/test/web/authentication.html">Testing Authentication</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/test/web/csrf.html">Testing CSRF</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../reactive/test/web/oauth2.html">Testing OAuth 2.0</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../reactive/configuration/webflux.html">WebFlux Security</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Spring Security</span>
<span class="version">5.6.1</span>
</div>
<ul class="components">
<li class="component is-current">
<a class="title" href="../../../index.html">Spring Security</a>
<ul class="versions">
<li class="version">
<a href="../../../6.0/index.html">6.0.0-SNAPSHOT</a>
</li>
<li class="version">
<a href="../../../6.0.0-M3/index.html">6.0.0-M3</a>
</li>
<li class="version">
<a href="../../../6.0.0-M2/index.html">6.0.0-M2</a>
</li>
<li class="version">
<a href="../../../6.0.0-M1/index.html">6.0.0-M1</a>
</li>
<li class="version">
<a href="../../../5.7/index.html">5.7.0-SNAPSHOT</a>
</li>
<li class="version">
<a href="../../../5.7.0-RC1/index.html">5.7.0-RC1</a>
</li>
<li class="version">
<a href="../../../5.7.0-M3/index.html">5.7.0-M3</a>
</li>
<li class="version">
<a href="../../../5.7.0-M2/index.html">5.7.0-M2</a>
</li>
<li class="version">
<a href="../../../5.7.0-M1/index.html">5.7.0-M1</a>
</li>
<li class="version">
<a href="../../../5.6.4/index.html">5.6.4-SNAPSHOT</a>
</li>
<li class="version is-latest">
<a href="../../../index.html">5.6.3</a>
</li>
<li class="version">
<a href="../../../5.6.2/index.html">5.6.2</a>
</li>
<li class="version is-current">
<a href="../../index.html">5.6.1</a>
</li>
<li class="version">
<a href="../../../5.6.0/index.html">5.6.0</a>
</li>
<li class="version">
<a href="../../../5.6.0-RC1/index.html">5.6.0-RC1</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main class="article">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../index.html">Spring Security</a></li>
<li><a href="../index.html">Features</a></li>
<li><a href="index.html">Protection Against Exploits</a></li>
<li><a href="csrf.html">CSRF</a></li>
</ul>
</nav>
<div class="search">
<input id="search-input" type="text" placeholder="Search docs">
</div>
<div class="page-versions">
<button class="version-menu-toggle" title="Show other versions of page">5.6.1</button>
<div class="version-menu">
<a class="version" href="../../../6.0/features/exploits/csrf.html">6.0.0-SNAPSHOT</a>
<a class="version" href="../../../6.0.0-M3/features/exploits/csrf.html">6.0.0-M3</a>
<a class="version" href="../../../6.0.0-M2/features/exploits/csrf.html">6.0.0-M2</a>
<a class="version" href="../../../6.0.0-M1/features/exploits/csrf.html">6.0.0-M1</a>
<a class="version" href="../../../5.7/features/exploits/csrf.html">5.7.0-SNAPSHOT</a>
<a class="version" href="../../../5.7.0-RC1/features/exploits/csrf.html">5.7.0-RC1</a>
<a class="version" href="../../../5.7.0-M3/features/exploits/csrf.html">5.7.0-M3</a>
<a class="version" href="../../../5.7.0-M2/features/exploits/csrf.html">5.7.0-M2</a>
<a class="version" href="../../../5.7.0-M1/features/exploits/csrf.html">5.7.0-M1</a>
<a class="version" href="../../../5.6.4/features/exploits/csrf.html">5.6.4-SNAPSHOT</a>
<a class="version" href="../../../features/exploits/csrf.html">5.6.3</a>
<a class="version" href="../../../5.6.2/features/exploits/csrf.html">5.6.2</a>
<a class="version is-current" href="csrf.html">5.6.1</a>
<a class="version" href="../../../5.6.0/features/exploits/csrf.html">5.6.0</a>
<a class="version" href="../../../5.6.0-RC1/features/exploits/csrf.html">5.6.0-RC1</a>
</div>
</div>
<div class="edit-this-page"><a href="https://github.com/spring-projects/spring-security/blob/5.6.1/docs/modules/ROOT/pages/features/exploits/csrf.adoc">Edit this Page</a></div>
</div>
<div class="content">
<aside class="toc sidebar" data-title="Contents" data-levels="2">
<div class="toc-menu"></div>
</aside>
<article class="doc">
<div class="admonitionblock important">
<table>
<tbody><tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p> For the latest stable version, please use <a href="../../../features/exploits/csrf.html">Spring Security 5.6.3</a>!</p>
</div>
</td>
</tr></tbody>
</table>
</div>
<h1 id="page-title" class="page">Cross Site Request Forgery (CSRF)</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Spring provides comprehensive support for protecting against <a href="https://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross Site Request Forgery (CSRF)</a> attacks.
In the following sections we will explore:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="csrf.html#csrf-explained">What is a CSRF Attack?</a></p>
</li>
<li>
<p><a href="csrf.html#csrf-protection">Protecting Against CSRF Attacks</a></p>
</li>
<li>
<p><a href="csrf.html#csrf-considerations">CSRF Considerations</a></p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This portion of the documentation discusses the general topic of CSRF protection.
Refer to the relevant sections for specific information on CSRF protection for <a href="../../servlet/exploits/csrf.html#servlet-csrf" class="xref page">servlet</a> and <a href="../../reactive/exploits/csrf.html#webflux-csrf" class="xref page">WebFlux</a> based applications.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="csrf-explained"><a class="anchor" href="csrf.html#csrf-explained"></a>What is a CSRF Attack?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The best way to understand a CSRF attack is by taking a look at a concrete example.</p>
</div>
<div class="paragraph">
<p>Assume that your bank&#8217;s website provides a form that allows transferring money from the currently logged in user to another bank account.
For example, the transfer form might look like:</p>
</div>
<div class="exampleblock">
<div class="title">Example 1. Transfer form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form method="post"
	action="/transfer"&gt;
&lt;input type="text"
	name="amount"/&gt;
&lt;input type="text"
	name="routingNumber"/&gt;
&lt;input type="text"
	name="account"/&gt;
&lt;input type="submit"
	value="Transfer"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The corresponding HTTP request might look like:</p>
</div>
<div class="exampleblock">
<div class="title">Example 2. Transfer HTTP request</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&amp;routingNumber=1234&amp;account=9876</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Now pretend you authenticate to your bank&#8217;s website and then, without logging out, visit an evil website.
The evil website contains an HTML page with the following form:</p>
</div>
<div class="exampleblock">
<div class="title">Example 3. Evil transfer form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form method="post"
	action="https://bank.example.com/transfer"&gt;
&lt;input type="hidden"
	name="amount"
	value="100.00"/&gt;
&lt;input type="hidden"
	name="routingNumber"
	value="evilsRoutingNumber"/&gt;
&lt;input type="hidden"
	name="account"
	value="evilsAccountNumber"/&gt;
&lt;input type="submit"
	value="Win Money!"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You like to win money, so you click on the submit button.
In the process, you have unintentionally transferred $100 to a malicious user.
This happens because, while the evil website cannot see your cookies, the cookies associated with your bank are still sent along with the request.</p>
</div>
<div class="paragraph">
<p>Worst yet, this whole process could have been automated using JavaScript.
This means you didn&#8217;t even need to click on the button.
Furthermore, it could just as easily happen when visiting an honest site that is a victim of a <a href="https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)">XSS attack</a>.
So how do we protect our users from such attacks?</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="csrf-protection"><a class="anchor" href="csrf.html#csrf-protection"></a>Protecting Against CSRF Attacks</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The reason that a CSRF attack is possible is that the HTTP request from the victim&#8217;s website and the request from the attacker&#8217;s website are exactly the same.
This means there is no way to reject requests coming from the evil website and allow requests coming from the bank&#8217;s website.
To protect against CSRF attacks we need to ensure there is something in the request that the evil site is unable to provide so we can differentiate the two requests.</p>
</div>
<div class="paragraph">
<p>Spring provides two mechanisms to protect against CSRF attacks:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <a href="csrf.html#csrf-protection-stp">Synchronizer Token Pattern</a></p>
</li>
<li>
<p>Specifying the <a href="csrf.html#csrf-protection-ssa">SameSite Attribute</a> on your session cookie</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Both protections require that <a href="csrf.html#csrf-protection-idempotent">Safe Methods Must be Idempotent</a></p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="csrf-protection-idempotent"><a class="anchor" href="csrf.html#csrf-protection-idempotent"></a>Safe Methods Must be Idempotent</h3>
<div class="paragraph">
<p>In order for <a href="csrf.html#csrf-protection">either protection</a> against CSRF to work, the application must ensure that <a href="https://tools.ietf.org/html/rfc7231#section-4.2.1">"safe" HTTP methods are idempotent</a>.
This means that requests with the HTTP method <code>GET</code>, <code>HEAD</code>, <code>OPTIONS</code>, and <code>TRACE</code> should not change the state of the application.</p>
</div>
</div>
<div class="sect2">
<h3 id="csrf-protection-stp"><a class="anchor" href="csrf.html#csrf-protection-stp"></a>Synchronizer Token Pattern</h3>
<div class="paragraph">
<p>The predominant and most comprehensive way to protect against CSRF attacks is to use the <a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern">Synchronizer Token Pattern</a>.
This solution is to ensure that each HTTP request requires, in addition to our session cookie, a secure random generated value called a CSRF token must be present in the HTTP request.</p>
</div>
<div class="paragraph">
<p>When an HTTP request is submitted, the server must look up the expected CSRF token and compare it against the actual CSRF token in the HTTP request.
If the values do not match, the HTTP request should be rejected.</p>
</div>
<div class="paragraph">
<p>The key to this working is that the actual CSRF token should be in a part of the HTTP request that is not automatically included by the browser.
For example, requiring the actual CSRF token in an HTTP parameter or an HTTP header will protect against CSRF attacks.
Requiring the actual CSRF token in a cookie does not work because cookies are automatically included in the HTTP request by the browser.</p>
</div>
<div class="paragraph">
<p>We can relax the expectations to only require the actual CSRF token for each HTTP request that updates state of the application.
For that to work, our application must ensure that <a href="csrf.html#csrf-protection-idempotent">safe HTTP methods are idempotent</a>.
This improves usability since we want to allow linking to our website using links from external sites.
Additionally, we do not want to include the random token in HTTP GET as this can cause the tokens to be leaked.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s take a look at how <a href="csrf.html#csrf-explained">our example</a> would change when using the Synchronizer Token Pattern.
Assume the actual CSRF token is required to be in an HTTP parameter named <code>_csrf</code>.
Our application&#8217;s transfer form would look like:</p>
</div>
<div class="exampleblock">
<div class="title">Example 4. Synchronizer Token Form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form method="post"
	action="/transfer"&gt;
&lt;input type="hidden"
	name="_csrf"
	value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/&gt;
&lt;input type="text"
	name="amount"/&gt;
&lt;input type="text"
	name="routingNumber"/&gt;
&lt;input type="hidden"
	name="account"/&gt;
&lt;input type="submit"
	value="Transfer"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The form now contains a hidden input with the value of the CSRF token.
External sites cannot read the CSRF token since the same origin policy ensures the evil site cannot read the response.</p>
</div>
<div class="paragraph">
<p>The corresponding HTTP request to transfer money would look like this:</p>
</div>
<div class="exampleblock">
<div class="title">Example 5. Synchronizer Token request</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&amp;routingNumber=1234&amp;account=9876&amp;_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You will notice that the HTTP request now contains the <code>_csrf</code> parameter with a secure random value.
The evil website will not be able to provide the correct value for the <code>_csrf</code> parameter (which must be explicitly provided on the evil website) and the transfer will fail when the server compares the actual CSRF token to the expected CSRF token.</p>
</div>
</div>
<div class="sect2">
<h3 id="csrf-protection-ssa"><a class="anchor" href="csrf.html#csrf-protection-ssa"></a>SameSite Attribute</h3>
<div class="paragraph">
<p>An emerging way to protect against <a href="csrf.html#csrf">CSRF Attacks</a> is to specify the <a href="https://tools.ietf.org/html/draft-west-first-party-cookies">SameSite Attribute</a> on cookies.
A server can specify the <code>SameSite</code> attribute when setting a cookie to indicate that the cookie should not be sent when coming from external sites.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Spring Security does not directly control the creation of the session cookie, so it does not provide support for the SameSite attribute.
<a href="https://spring.io/projects/spring-session">Spring Session</a> provides support for the <code>SameSite</code> attribute in servlet based applications.
Spring Framework&#8217;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/server/session/CookieWebSessionIdResolver.html">CookieWebSessionIdResolver</a> provides out of the box support for the <code>SameSite</code> attribute in WebFlux based applications.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>An example, HTTP response header with the <code>SameSite</code> attribute might look like:</p>
</div>
<div class="exampleblock">
<div class="title">Example 6. SameSite HTTP response</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Valid values for the <code>SameSite</code> attribute are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Strict</code> - when specified any request coming from the <a href="https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-2.1">same-site</a> will include the cookie.
Otherwise, the cookie will not be included in the HTTP request.</p>
</li>
<li>
<p><code>Lax</code> - when specified cookies will be sent when coming from the <a href="https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-2.1">same-site</a> or when the request comes from top-level navigations and the <a href="csrf.html#csrf-protection-idempotent">method is idempotent</a>.
Otherwise, the cookie will not be included in the HTTP request.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Let&#8217;s take a look at how <a href="csrf.html#csrf-explained">our example</a> could be protected using the <code>SameSite</code> attribute.
The bank application can protect against CSRF by specifying the <code>SameSite</code> attribute on the session cookie.</p>
</div>
<div class="paragraph">
<p>With the <code>SameSite</code> attribute set on our session cookie, the browser will continue to send the <code>JSESSIONID</code> cookie with requests coming from the banking website.
However, the browser will no longer send the <code>JSESSIONID</code> cookie with a transfer request coming from the evil website.
Since the session is no longer present in the transfer request coming from the evil website, the application is protected from the CSRF attack.</p>
</div>
<div class="paragraph">
<p>There are some important <a href="https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-5">considerations</a> that one should be aware about when using <code>SameSite</code> attribute to protect against CSRF attacks.</p>
</div>
<div class="paragraph">
<p>Setting the <code>SameSite</code> attribute to <code>Strict</code> provides a stronger defense but can confuse users.
Consider a user that stays logged into a social media site hosted at <a href="https://social.example.com" class="bare">https://social.example.com</a>.
The user receives an email at <a href="https://email.example.org" class="bare">https://email.example.org</a> that includes a link to the social media site.
If the user clicks on the link, they would rightfully expect to be authenticated to the social media site.
However, if the <code>SameSite</code> attribute is <code>Strict</code> the cookie would not be sent and so the user would not be authenticated.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>We could improve the protection and usability of <code>SameSite</code> protection against CSRF attacks by implementing <a href="https://github.com/spring-projects/spring-security/issues/7537">gh-7537</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Another obvious consideration is that in order for the <code>SameSite</code> attribute to protect users, the browser must support the <code>SameSite</code> attribute.
Most modern browsers do <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/headers/Set-Cookie#Browser_compatibility">support the SameSite attribute</a>.
However, older browsers that are still in use may not.</p>
</div>
<div class="paragraph">
<p>For this reason, it is generally recommended to use the <code>SameSite</code> attribute as a defense in depth rather than the sole protection against CSRF attacks.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="csrf-when"><a class="anchor" href="csrf.html#csrf-when"></a>When to use CSRF protection</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When should you use CSRF protection?
Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users.
If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.</p>
</div>
<div class="sect2">
<h3 id="csrf-when-json"><a class="anchor" href="csrf.html#csrf-when-json"></a>CSRF protection and JSON</h3>
<div class="paragraph">
<p>A common question is "do I need to protect JSON requests made by javascript?"
The short answer is, it depends.
However, you must be very careful as there are CSRF exploits that can impact JSON requests.
For example, a malicious user can create a <a href="http://blog.opensecurityresearch.com/2012/02/json-csrf-with-parameter-padding.html">CSRF with JSON using the following form</a>:</p>
</div>
<div class="exampleblock">
<div class="title">Example 7. CSRF with JSON form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form action="https://bank.example.com/transfer" method="post" enctype="text/plain"&gt;
	&lt;input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'&gt;
	&lt;input type="submit"
		value="Win Money!"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>This will produce the following JSON structure</p>
</div>
<div class="exampleblock">
<div class="title">Example 8. CSRF with JSON request</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">{ "amount": 100,
"routingNumber": "evilsRoutingNumber",
"account": "evilsAccountNumber",
"ignore_me": "=test"
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If an application were not validating the Content-Type, then it would be exposed to this exploit.
Depending on the setup, a Spring MVC application that validates the Content-Type could still be exploited by updating the URL suffix to end with <code>.json</code> as shown below:</p>
</div>
<div class="exampleblock">
<div class="title">Example 9. CSRF with JSON Spring MVC form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain"&gt;
	&lt;input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'&gt;
	&lt;input type="submit"
		value="Win Money!"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="csrf-when-stateless"><a class="anchor" href="csrf.html#csrf-when-stateless"></a>CSRF and Stateless Browser Applications</h3>
<div class="paragraph">
<p>What if my application is stateless?
That doesn&#8217;t necessarily mean you are protected.
In fact, if a user does not need to perform any actions in the web browser for a given request, they are likely still vulnerable to CSRF attacks.</p>
</div>
<div class="paragraph">
<p>For example, consider an application that uses a custom cookie that contains all the state within it for authentication instead of the JSESSIONID.
When the CSRF attack is made the custom cookie will be sent with the request in the same manner that the JSESSIONID cookie was sent in our previous example.
This application will be vulnerable to CSRF attacks.</p>
</div>
<div class="paragraph">
<p>Applications that use basic authentication are also vulnerable to CSRF attacks.
The application is vulnerable since the browser will automatically include the username and password in any requests in the same manner that the JSESSIONID cookie was sent in our previous example.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="csrf-considerations"><a class="anchor" href="csrf.html#csrf-considerations"></a>CSRF Considerations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are a few special considerations to consider when implementing protection against CSRF attacks.</p>
</div>
<div class="sect2">
<h3 id="csrf-considerations-login"><a class="anchor" href="csrf.html#csrf-considerations-login"></a>Logging In</h3>
<div class="paragraph">
<p>In order to protect against <a href="https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests">forging log in requests</a> the log in HTTP request should be protected against CSRF attacks.
Protecting against forging log in requests is necessary so that a malicious user cannot read a victim&#8217;s sensitive information.
The attack is performed as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A malicious user performs a CSRF log in using the malicious user&#8217;s credentials.
The victim is now authenticated as the malicious user.</p>
</li>
<li>
<p>The malicious user then tricks the victim to visit the compromised website and enter sensitive information</p>
</li>
<li>
<p>The information is associated to the malicious user&#8217;s account so the malicious user can log in with their own credentials and view the vicitim&#8217;s sensitive information</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A possible complication to ensuring log in HTTP requests are protected against CSRF attacks is that the user might experience a session timeout that causes the request to be rejected.
A session timeout is surprising to users who do not expect to need to have a session in order to log in.
For more information refer to <a href="csrf.html#csrf-considerations-timeouts">CSRF and Session Timeouts</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="csrf-considerations-logout"><a class="anchor" href="csrf.html#csrf-considerations-logout"></a>Logging Out</h3>
<div class="paragraph">
<p>In order to protect against forging log out requests, the log out HTTP request should be protected against CSRF attacks.
Protecting against forging log out requests is necessary so a malicious user cannot read a victim&#8217;s sensitive information.
For details on the attack refer to <a href="https://labs.detectify.com/2017/03/15/loginlogout-csrf-time-to-reconsider/">this blog post</a>.</p>
</div>
<div class="paragraph">
<p>A possible complication to ensuring log out HTTP requests are protected against CSRF attacks is that the user might experience a session timeout that causes the request to be rejected.
A session timeout is surprising to users who do not expect to need to have a session in order to log out.
For more information refer to <a href="csrf.html#csrf-considerations-timeouts">CSRF and Session Timeouts</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="csrf-considerations-timeouts"><a class="anchor" href="csrf.html#csrf-considerations-timeouts"></a>CSRF and Session Timeouts</h3>
<div class="paragraph">
<p>More often than not, the expected CSRF token is stored in the session.
This means that as soon as the session expires the server will not find an expected CSRF token and reject the HTTP request.
There are a number of options to solve timeouts each of which come with trade offs.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The best way to mitigate the timeout is by using JavaScript to request a CSRF token on form submission.
The form is then updated with the CSRF token and submitted.</p>
</li>
<li>
<p>Another option is to have some JavaScript that lets the user know their session is about to expire.
The user can click a button to continue and refresh the session.</p>
</li>
<li>
<p>Finally, the expected CSRF token could be stored in a cookie.
This allows the expected CSRF token to outlive the session.</p>
<div class="paragraph">
<p>One might ask why the expected CSRF token isn&#8217;t stored in a cookie by default.
This is because there are known exploits in which headers (for example, to specify the cookies) can be set by another domain.
This is the same reason Ruby on Rails <a href="https://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails/">no longer skips CSRF checks when the header X-Requested-With is present</a>.
See <a href="https://web.archive.org/web/20210221120355/https://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2011-February/007533.html">this webappsec.org thread</a> for details on how to perform the exploit.
Another disadvantage is that by removing the state (that is, the timeout), you lose the ability to forcibly invalidate the token if it is compromised.</p>
</div>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="csrf-considerations-multipart"><a class="anchor" href="csrf.html#csrf-considerations-multipart"></a>Multipart (file upload)</h3>
<div class="paragraph">
<p>Protecting multipart requests (file uploads) from CSRF attacks causes a <a href="https://en.wikipedia.org/wiki/Chicken_or_the_egg">chicken and the egg</a> problem.
In order to prevent a CSRF attack from occurring, the body of the HTTP request must be read to obtain actual CSRF token.
However, reading the body means that the file will be uploaded which means an external site can upload a file.</p>
</div>
<div class="paragraph">
<p>There are two options to using CSRF protection with multipart/form-data.
Each option has its trade-offs.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="csrf.html#csrf-considerations-multipart-body">Place CSRF Token in the Body</a></p>
</li>
<li>
<p><a href="csrf.html#csrf-considerations-multipart-url">Place CSRF Token in the URL</a></p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Before you integrate Spring Security&#8217;s CSRF protection with multipart file upload, ensure that you can upload without the CSRF protection first.
More information about using multipart forms with Spring can be found within the <a href="https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-multipart">1.1.11. Multipart Resolver</a> section of the Spring reference and the <a href="https://docs.spring.io/spring/docs/5.2.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html">MultipartFilter javadoc</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="csrf-considerations-multipart-body"><a class="anchor" href="csrf.html#csrf-considerations-multipart-body"></a>Place CSRF Token in the Body</h4>
<div class="paragraph">
<p>The first option is to include the actual CSRF token in the body of the request.
By placing the CSRF token in the body, the body will be read before authorization is performed.
This means that anyone can place temporary files on your server.
However, only authorized users will be able to submit a file that is processed by your application.
In general, this is the recommended approach because the temporary file upload should have a negligible impact on most servers.</p>
</div>
</div>
<div class="sect3">
<h4 id="csrf-considerations-multipart-url"><a class="anchor" href="csrf.html#csrf-considerations-multipart-url"></a>Include CSRF Token in URL</h4>
<div class="paragraph">
<p>If allowing unauthorized users to upload temporary files is not acceptable, an alternative is to include the expected CSRF token as a query parameter in the action attribute of the form.
The disadvantage to this approach is that query parameters can be leaked.
More generally, it is considered best practice to place sensitive data within the body or headers to ensure it is not leaked.
Additional information can be found in <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3">RFC 2616 Section 15.1.3 Encoding Sensitive Information in URI&#8217;s</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="csrf-considerations-override-method"><a class="anchor" href="csrf.html#csrf-considerations-override-method"></a>HiddenHttpMethodFilter</h4>
<div class="paragraph">
<p>In some applications a form parameter can be used to override the HTTP method.
For example, the form below could be used to treat the HTTP method as a <code>delete</code> rather than a <code>post</code>.</p>
</div>
<div class="exampleblock">
<div class="title">Example 10. CSRF Hidden HTTP Method Form</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-html hljs" data-lang="html">&lt;form action="/process"
	method="post"&gt;
	&lt;!-- ... --&gt;
	&lt;input type="hidden"
		name="_method"
		value="delete"/&gt;
&lt;/form&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Overriding the HTTP method occurs in a filter.
That filter must be placed before Spring Security&#8217;s support.
Note that overriding only happens on a <code>post</code>, so this is actually unlikely to cause any real problems.
However, it is still best practice to ensure it is placed before Spring Security&#8217;s filters.</p>
</div>
</div>
</div>
</div>
</div>
<nav class="pagination">
<span class="prev"><a href="index.html">Protection Against Exploits</a></span>
<span class="next"><a href="headers.html">HTTP Headers</a></span>
</nav>
</article>
</div>
</main>
</div>
<footer class="footer flex">
<div id="spring-links flex">
<img id="springlogo" src="../../../_/img/spring-logo.svg" alt="Spring">
<p class="smallest antialiased">© <script>var d = new Date();
        document.write(d.getFullYear());</script> <a href="https://www.vmware.com/">VMware</a>, Inc. or its affiliates. <a href="https://www.vmware.com/help/legal.html">Terms of Use</a> • <a href="https://www.vmware.com/help/privacy.html" rel="noopener noreferrer">Privacy</a> • <a href="https://spring.io/trademarks">Trademark Guidelines</a> <span id="thank-you-mobile">• <a href="https://spring.io/thank-you">Thank you</a></span> • <a href="https://www.vmware.com/help/privacy/california-privacy-rights.html">Your California Privacy Rights</a> • <a class="ot-sdk-show-settings">Cookie Settings</a> <span id="teconsent"></span></p>
<p class="smallest antialiased">Apache®, Apache Tomcat®, Apache Kafka®, Apache Cassandra&trade;, and Apache Geode&trade; are trademarks or registered trademarks of the Apache Software Foundation in the United States and/or other countries. Java&trade;, Java&trade; SE, Java&trade; EE, and OpenJDK&trade; are trademarks of Oracle and/or its affiliates. Kubernetes® is a registered trademark of the Linux Foundation in the United States and other countries. Linux® is the registered trademark of Linus Torvalds in the United States and other countries. Windows® and Microsoft® Azure are registered trademarks of Microsoft Corporation. “AWS” and “Amazon Web Services” are trademarks or registered trademarks of Amazon.com Inc. or its affiliates. All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes. Other names may be trademarks of their respective owners.</p>
</div>
<div id="social-icons" class="flex jc-between">
<a href="https://www.youtube.com/user/SpringSourceDev" title="Youtube"><svg id="youtube-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><circle class="cls-1" cx="20" cy="20" r="20" /><path class="cls-2" d="M30.91,14.53a2.89,2.89,0,0,0-2-2C27.12,12,20,12,20,12s-7.12,0-8.9.47a2.9,2.9,0,0,0-2,2A30.56,30.56,0,0,0,8.63,20a30.44,30.44,0,0,0,.46,5.47,2.89,2.89,0,0,0,2,2C12.9,28,20,28,20,28s7.12,0,8.9-.47a2.87,2.87,0,0,0,2-2A30.56,30.56,0,0,0,31.37,20,28.88,28.88,0,0,0,30.91,14.53ZM17.73,23.41V16.59L23.65,20Z" /></svg></a>
<a href="https://github.com/spring-projects" title="Github"><svg id="github-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75.93 75.93"><path class="cls-1" d="M38,0a38,38,0,1,0,38,38A38,38,0,0,0,38,0Z" /></g><path class="cls-2" d="M38,15.59A22.95,22.95,0,0,0,30.71,60.3c1.15.21,1.57-.5,1.57-1.11s0-2,0-3.9c-6.38,1.39-7.73-3.07-7.73-3.07A6.09,6.09,0,0,0,22,48.86c-2.09-1.42.15-1.39.15-1.39a4.81,4.81,0,0,1,3.52,2.36c2,3.5,5.37,2.49,6.67,1.91a4.87,4.87,0,0,1,1.46-3.07c-5.09-.58-10.45-2.55-10.45-11.34a8.84,8.84,0,0,1,2.36-6.15,8.29,8.29,0,0,1,.23-6.07s1.92-.62,6.3,2.35a21.82,21.82,0,0,1,11.49,0c4.38-3,6.3-2.35,6.3-2.35a8.29,8.29,0,0,1,.23,6.07,8.84,8.84,0,0,1,2.36,6.15c0,8.81-5.37,10.75-10.48,11.32a5.46,5.46,0,0,1,1.56,4.25c0,3.07,0,5.54,0,6.29s.42,1.33,1.58,1.1A22.94,22.94,0,0,0,38,15.59Z" /></svg></a>
<a href="https://twitter.com/springcentral" title="Twitter"><svg id="twitter-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75.93 75.93"><circle class="cls-1" cx="37.97" cy="37.97" r="37.97" /><path id="Twitter-2" data-name="Twitter" class="cls-2" d="M55.2,22.73a15.43,15.43,0,0,1-4.88,1.91,7.56,7.56,0,0,0-5.61-2.49A7.78,7.78,0,0,0,37,30a7.56,7.56,0,0,0,.2,1.79,21.63,21.63,0,0,1-15.84-8.23,8,8,0,0,0,2.37,10.52,7.66,7.66,0,0,1-3.48-1v.09A7.84,7.84,0,0,0,26.45,41a7.54,7.54,0,0,1-2,.28A7.64,7.64,0,0,1,23,41.09a7.71,7.71,0,0,0,7.18,5.47,15.21,15.21,0,0,1-9.55,3.37,15.78,15.78,0,0,1-1.83-.11,21.41,21.41,0,0,0,11.78,3.54c14.13,0,21.86-12,21.86-22.42,0-.34,0-.68,0-1a15.67,15.67,0,0,0,3.83-4.08,14.9,14.9,0,0,1-4.41,1.24A7.8,7.8,0,0,0,55.2,22.73Z" /></svg></a>
</div>
</footer>
<script src="../../../_/js/site.js"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>
<script async src="../../../_/js/vendor/tabs.js"></script>
<script src="../../../_/js/vendor/switchtheme.js"></script>
<script src="../../../_/js/vendor/docsearch.min.js"></script>

<script>
var search = docsearch({
  appId: '244V8V9FGG',
  apiKey: '82c7ead946afbac3cf98c32446154691',
  indexName: 'security-docs',
  inputSelector: '#search-input',
  autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
  algoliaOptions: { hitsPerPage: 10 }
}).autocomplete
search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
</script>
<script>if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}</script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"702d377da83a97ee","token":"bffcb8a918ae4755926f76178bfbd26b","version":"2021.12.0","si":100}' crossorigin="anonymous"></script>
</body>
</html>
